package com.black.utils.converter;

import com.alibaba.fastjson2.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;
import org.jsoup.nodes.TextNode;
import org.jsoup.select.NodeTraversor;
import org.jsoup.select.NodeVisitor;

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author ylx
 */
public class RichTextConverter
{

    // HTML标签常量
    public static final String PARAGRAPH = "<p>";

    public static final String _PARAGRAPH = "</p>";

    public static final String SPAN = "<span>";

    public static final String _SPAN = "</span>";

    public static final String SPACE = "&nbsp;";

    public static final String LINE_BREAK = "<p><br/></p>";

    // 自定义字段属性常量
    public static final String CUSTOM_ATTR = "data-w-e-type=\"customField\"";

    public static final String VOID_ATTR = "data-w-e-is-void=\"\"";

    public static final String INLINE_ATTR = "data-w-e-is-inline=\"\"";

    public static final String VALUE_ATTR = "data-value=\"";

    public static final String LABEL_ATTR = "data-label=\"";

    // HTML标签名称常量
    public static final String TAG_P = "p";

    public static final String TAG_BR = "br";

    public static final String TAG_SPAN = "span";

    public static final String CUSTOM_FIELD_TYPE = "customField";

    public static final char LINE_BREAK_CHAR = '\n';

    /**
     * 将纯文本转换为HTML
     *
     * @param dictionary 占位符映射字典 (key: 占位符如"%告警时间%", value: 对应值如"alarmTime")
     * @param content    纯文本内容
     * @return HTML格式字符串
     */
    public static String buildHtml(JSONObject dictionary, String content)
    {
        if (content == null)
            return null;
        if (content.contains(SPAN) || content.contains(PARAGRAPH))
            return content;

        String[] lines = content.split(String.valueOf(LINE_BREAK_CHAR));
        StringBuilder html = new StringBuilder();

        // 构建正则表达式模式，匹配所有字典中的占位符
        Pattern pattern = buildPlaceholderPattern(dictionary);

        for (String line : lines)
        {
            if (line.trim().isEmpty())
            {
                html.append(LINE_BREAK);
                continue;
            }

            StringBuilder processedLine = new StringBuilder();
            Matcher matcher = pattern.matcher(line);

            int lastEnd = 0;
            while (matcher.find())
            {
                // 添加前面的普通文本
                if (matcher.start() > lastEnd)
                {
                    String normalText = line.substring(lastEnd, matcher.start());
                    processedLine.append(normalText);
                }

                // 添加自定义字段
                String placeholder = matcher.group();
                processedLine.append(buildCustomFieldHtml(dictionary, placeholder));

                lastEnd = matcher.end();
            }

            // 添加剩余文本
            if (lastEnd < line.length())
            {
                processedLine.append(line.substring(lastEnd));
            }

            html.append(PARAGRAPH).append(processedLine).append(_PARAGRAPH);
        }

        return html.toString();
    }

    /**
     * 将HTML转换为纯文本
     *
     * @param content HTML内容
     * @return 纯文本
     */
    public static String parseText(String content)
    {
        if (content == null)
            return null;

        Document doc = Jsoup.parse(content);
        StringBuilder sb = new StringBuilder();

        NodeTraversor.traverse(new NodeVisitor()
        {
            private boolean lastWasNewLine = false;

            @Override
            public void head(Node node, int depth)
            {
                if (node instanceof Element)
                {
                    Element el = (Element)node;

                    // 处理自定义字段
                    // if (isCustomField(el))
                    //{
                    //    sb.append(el.attr(LABEL_ATTR.replace("=\"", "").replace("\"", "")));
                    //}
                    // 处理BR标签
                    if (el.tagName().equals(TAG_BR) && !lastWasNewLine)
                    {
                        sb.append(LINE_BREAK_CHAR);
                        lastWasNewLine = true;
                    }
                }
                // 处理文本节点
                else if (node instanceof TextNode)
                {
                    String text = ((TextNode)node).text().trim();
                    if (!text.isEmpty())
                    {
                        sb.append(text);
                        lastWasNewLine = false;
                    }
                }
            }

            @Override
            public void tail(Node node, int depth)
            {
                if (node instanceof Element)
                {
                    Element el = (Element)node;

                    // 处理P标签结尾
                    if (el.tagName().equals(TAG_P))
                    {
                        if (sb.length() > 0 && sb.charAt(sb.length() - 1) != LINE_BREAK_CHAR)
                        {
                            sb.append(LINE_BREAK_CHAR);
                            lastWasNewLine = true;
                        }
                    }
                }
            }
        }, doc.body());

        // 清理尾部多余换行
        while (sb.length() > 0 && sb.charAt(sb.length() - 1) == LINE_BREAK_CHAR)
        {
            sb.deleteCharAt(sb.length() - 1);
        }

        return sb.toString();
    }

    /**
     * 构建占位符正则表达式模式
     */
    private static Pattern buildPlaceholderPattern(JSONObject dictionary)
    {
        // 按长度降序排序，确保长字符串优先匹配
        String patternStr = dictionary.keySet().stream()
            .sorted((s1, s2) -> s2.length() - s1.length())
            .map(Pattern::quote)
            .collect(Collectors.joining("|"));

        return Pattern.compile(patternStr);
    }

    /**
     * 判断元素是否为自定义字段
     */
    private static boolean isCustomField(Element el)
    {
        return CUSTOM_FIELD_TYPE.equals(el.attr(CUSTOM_ATTR.split("=")[0])) &&
            el.hasAttr(VOID_ATTR.split("=")[0]) &&
            el.hasAttr(INLINE_ATTR.split("=")[0]);
    }

    /**
     * 构建自定义字段HTML
     */
    private static String buildCustomFieldHtml(JSONObject dictionary, String placeholder)
    {
        String dataValue = (String) dictionary.getOrDefault(placeholder, placeholder);

        return "<" + TAG_SPAN + " " +
            CUSTOM_ATTR + " " +
            VOID_ATTR + " " +
            INLINE_ATTR + " " +
            VALUE_ATTR + dataValue + "\" " +
            LABEL_ATTR + placeholder + "\">" +
            placeholder +
            _SPAN;
    }
}